package com.fangcang.ebk.common.controller;

import com.fangcang.common.PaginationSupportDTO;
import com.fangcang.common.ResponseDTO;
import com.fangcang.common.enums.ErrorCodeEnum;
import com.fangcang.common.enums.ResultCodeEnum;
import com.fangcang.common.util.MD5Util;
import com.fangcang.common.util.StringUtil;
import com.fangcang.ebk.common.constant.CommonConstant;
import com.fangcang.ebk.common.dto.EbkUserDTO;
import com.fangcang.ebk.common.dto.MerchantUserDTO;
import com.fangcang.ebk.request.EbkUserLoginDTO;
import com.fangcang.merchant.domain.UserDO;
import com.fangcang.merchant.dto.MerchantDTO;
import com.fangcang.merchant.dto.QueryUserConditionDTO;
import com.fangcang.merchant.request.QueryMerchantDTO;
import com.fangcang.merchant.service.MerchantService;
import com.fangcang.merchant.service.UserService;
import com.fangcang.message.remote.WxAuth2Remote;
import com.fangcang.message.remote.response.weixin.WxVisitIdResponseDTO;
import com.fangcang.supplier.domain.SupplyUserBindDO;
import com.fangcang.supplier.dto.MerchantOPDTO;
import com.fangcang.supplier.request.QuerySupplyUserBindDTO;
import com.fangcang.supplier.request.SingleUserRequestDTO;
import com.fangcang.supplier.response.SingleSupplyInfoResponseDTO;
import com.fangcang.supplier.response.SingleUserResponseDTO;
import com.fangcang.supplier.service.SupplyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

@RestController
@Slf4j
@RequestMapping(("/ebk"))
public class LoginController extends BaseController{

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private UserService userService;

    @Autowired
    private SupplyService supplyService;

    @Autowired
    protected WxAuth2Remote wxAuth2Remote;

    @RequestMapping(value = "/login" , method = RequestMethod.POST, produces = { "application/json;charset=UTF-8" })
    @ResponseBody
    public ResponseDTO login(@RequestBody EbkUserLoginDTO requestDTO){
        ResponseDTO responseDTO=null;
        try{
            //根据域名查询商家
            QueryMerchantDTO queryMerchantDTO=new QueryMerchantDTO();
            queryMerchantDTO.setEbkDomain(super.getRequest().getServerName());
            MerchantDTO merchantDTO=merchantService.queryMerchant(queryMerchantDTO);
            if (merchantDTO==null){
                responseDTO=new ResponseDTO(ResultCodeEnum.FAILURE.code,null,"商家不存在");
                return responseDTO;
            }
            //查询供应商用户
            SingleUserRequestDTO singleUserRequestDTO=new SingleUserRequestDTO();
            singleUserRequestDTO.setMerchantId(merchantDTO.getMerchantId());
            singleUserRequestDTO.setUserName(requestDTO.getUserLoginName());
            ResponseDTO<SingleUserResponseDTO> singleUserResponseDTO=supplyService.getUserInfo(singleUserRequestDTO);
            if (singleUserResponseDTO.getResult()==ResultCodeEnum.FAILURE.code){
                responseDTO=new ResponseDTO(ResultCodeEnum.FAILURE.code);
                responseDTO.setFailReason(singleUserResponseDTO.getFailReason());
            }else if(singleUserResponseDTO.getModel()==null || singleUserResponseDTO.getModel().getIsActive()==0) {
                responseDTO=new ResponseDTO(ResultCodeEnum.FAILURE.code);
                responseDTO.setFailReason("用户不存在");
            }else if(!singleUserResponseDTO.getModel().getPassword().equals(MD5Util.encode(requestDTO.getUserPwd()))){
                responseDTO=new ResponseDTO(ResultCodeEnum.FAILURE.code);
                responseDTO.setFailReason("密码不正确");
            }else{
                //校验通过
                responseDTO=new ResponseDTO(ResultCodeEnum.SUCCESS.code);
                EbkUserDTO ebkUserDTO=new EbkUserDTO();
                ebkUserDTO.setMerchantCode(merchantDTO.getMerchantCode());
                ebkUserDTO.setMerchantName(merchantDTO.getMerchantName());
                ebkUserDTO.setSystemName(merchantDTO.getSystemName());
                ebkUserDTO.setEbkName(merchantDTO.getEbkName());
                BeanUtils.copyProperties(singleUserResponseDTO.getModel(),ebkUserDTO);

                //查询供应商信息
                SingleUserRequestDTO supplyRequestDTO=new SingleUserRequestDTO();
                supplyRequestDTO.setSupplyId(singleUserResponseDTO.getModel().getSupplyId());
                ResponseDTO<SingleSupplyInfoResponseDTO> supplyInfoResponseDTO=supplyService.getSupplyById(supplyRequestDTO);
                if (supplyInfoResponseDTO.getResult()==ResultCodeEnum.SUCCESS.code
                        && supplyInfoResponseDTO.getModel()!=null){
                    ebkUserDTO.setSupplyCode(supplyInfoResponseDTO.getModel().getSupplyCode());
                    ebkUserDTO.setSupplyName(supplyInfoResponseDTO.getModel().getSupplyName());

                    MerchantUserDTO merchantPM=new MerchantUserDTO();
                    merchantPM.setUserId(supplyInfoResponseDTO.getModel().getMerchantPM());
                    merchantPM.setUserName(supplyInfoResponseDTO.getModel().getMerchantPMName());
                    if (merchantPM.getUserId()!=null && merchantPM.getUserId()!=0){
                        QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                        queryPMConditionDTO.setUserId(merchantPM.getUserId());
                        PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                        if (userForPage.getTotalCount()>0){
                            merchantPM.setPhone(userForPage.getItemList().get(0).getPhone());
                            merchantPM.setQq(userForPage.getItemList().get(0).getQq());
                            merchantPM.setEmail(userForPage.getItemList().get(0).getEmail());
                            merchantPM.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                        }
                    }
                    ebkUserDTO.setMerchantPM(merchantPM);

                    MerchantUserDTO merchantBM=new MerchantUserDTO();
                    merchantBM.setUserId(supplyInfoResponseDTO.getModel().getMerchantBM());
                    merchantBM.setUserName(supplyInfoResponseDTO.getModel().getMerchantBMName());
                    if (merchantBM.getUserId()!=null && merchantBM.getUserId()!=0){
                        QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                        queryPMConditionDTO.setUserId(merchantBM.getUserId());
                        PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                        if (userForPage.getTotalCount()>0){
                            merchantBM.setPhone(userForPage.getItemList().get(0).getPhone());
                            merchantBM.setQq(userForPage.getItemList().get(0).getQq());
                            merchantBM.setEmail(userForPage.getItemList().get(0).getEmail());
                            merchantBM.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                        }
                    }
                    ebkUserDTO.setMerchantBM(merchantBM);

                    MerchantUserDTO merchantFinancer=new MerchantUserDTO();
                    merchantFinancer.setUserId(supplyInfoResponseDTO.getModel().getMerchantFinancer());
                    merchantFinancer.setUserName(supplyInfoResponseDTO.getModel().getMerchantFinancerName());
                    if (merchantFinancer.getUserId()!=null && merchantFinancer.getUserId()!=0){
                        QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                        queryPMConditionDTO.setUserId(merchantFinancer.getUserId());
                        PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                        if (userForPage.getTotalCount()>0){
                            merchantFinancer.setPhone(userForPage.getItemList().get(0).getPhone());
                            merchantFinancer.setQq(userForPage.getItemList().get(0).getQq());
                            merchantFinancer.setEmail(userForPage.getItemList().get(0).getEmail());
                            merchantFinancer.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                        }
                    }
                    ebkUserDTO.setMerchantFinancer(merchantFinancer);

                    ebkUserDTO.setMerchantOPList(new ArrayList<>());
                    if (supplyInfoResponseDTO.getModel().getMerchantOPs()!=null
                            && supplyInfoResponseDTO.getModel().getMerchantOPs().size()>0){
                        for (MerchantOPDTO merchantOPDTO:supplyInfoResponseDTO.getModel().getMerchantOPs()){
                            MerchantUserDTO merchantOP=new MerchantUserDTO();
                            merchantOP.setUserId(merchantOPDTO.getMerchantOP());
                            merchantOP.setUserName(merchantOPDTO.getMerchantOPName());
                            if (merchantOP.getUserId()!=null && merchantOP.getUserId()!=0){
                                QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                                queryPMConditionDTO.setUserId(merchantOP.getUserId());
                                PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                                if (userForPage.getTotalCount()>0){
                                    merchantOP.setPhone(userForPage.getItemList().get(0).getPhone());
                                    merchantOP.setQq(userForPage.getItemList().get(0).getQq());
                                    merchantOP.setEmail(userForPage.getItemList().get(0).getEmail());
                                    merchantOP.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                                }
                            }
                            ebkUserDTO.getMerchantOPList().add(merchantOP);
                        }
                    }
                }
                //微信绑定自动登录
                if(StringUtil.isValidString(super.getCacheVisitWxOpenId())){
                    SupplyUserBindDO supplyUserBindDO=new SupplyUserBindDO();
                    supplyUserBindDO.setMerchantCode(merchantDTO.getMerchantCode());
                    supplyUserBindDO.setSupplyCode(supplyInfoResponseDTO.getModel().getSupplyCode());
                    supplyUserBindDO.setUserId(singleUserResponseDTO.getModel().getUserId());
                    supplyUserBindDO.setOpenId(super.getCacheVisitWxOpenId());
                    supplyUserBindDO.setCreator(singleUserResponseDTO.getModel().getUserName());
                    supplyUserBindDO.setCreateTime(new Date());
                    supplyService.saveSupplyUserBind(supplyUserBindDO);
                }
                super.getSession().setAttribute(CommonConstant.SESSION_SYSUSER,ebkUserDTO);
                responseDTO.setModel(ebkUserDTO);
            }
        }catch (Exception e){
            log.error("supplyService.getUserInfo 异常",e);
            responseDTO=new ResponseDTO(ResultCodeEnum.FAILURE.code,null, ErrorCodeEnum.SYSTEM_EXCEPTION.errorDesc);
        }
        return responseDTO;
    }

    @RequestMapping(value = "/logout" , method = RequestMethod.POST, produces = { "application/json;charset=UTF-8" })
    @ResponseBody
    public ResponseDTO logout(){
        super.getSession().setAttribute(CommonConstant.SESSION_SYSUSER,null);
        return new ResponseDTO(ResultCodeEnum.SUCCESS.code);
    }

    @RequestMapping(value = "/checkLogin" , method = RequestMethod.POST, produces = { "application/json;charset=UTF-8" })
    @ResponseBody
    public ResponseDTO checkLogin(){
        ResponseDTO response=null;
        EbkUserDTO sysUser=super.getCacheUser();
        if (sysUser==null){
            response=new ResponseDTO(ResultCodeEnum.FAILURE.code);
        }else{
            response=new ResponseDTO(ResultCodeEnum.SUCCESS.code);
            response.setModel(sysUser);
        }
        return response;
    }

    /**
     * 微信回调地址，根据微信回传code获取微信openID
     */
    @RequestMapping(value = { "/wxBusDispatcher.shtml" })
    public ModelAndView wxBusDispatcher(String code, HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("wxBusDispatcher获取用户openid   code=["+code+"]");

        if(StringUtils.isBlank(code)){
            StringBuilder errorInfo = new StringBuilder("微信自动获取用户openid失败：code为空\n");
            errorInfo.append("请求URL连接参数：").append(this.getRequest().getQueryString()).append("\n");

            Enumeration headerNames = this.getRequest().getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String key = (String) headerNames.nextElement();
                errorInfo.append(key).append(":").append(this.getRequest().getHeader(key)).append("\n");
            }
            log.error(errorInfo.toString());

            /*ModelAndView modelAndView = new ModelAndView("common/systemError");
            modelAndView.addObject("errorMsg", "系统繁忙，请您稍后再试。");
            return modelAndView;*/
            return null;
        }

        try{
            //获取访问者openid，设置进session中
            ResponseDTO<WxVisitIdResponseDTO> visitIdResponse = wxAuth2Remote.getVisitWeixinId(code);
            if (visitIdResponse.getResult()== ResultCodeEnum.FAILURE.code
                    || visitIdResponse.getModel()==null) {
                /*ModelAndView modelAndView = new ModelAndView("common/systemError");
                modelAndView.addObject("errorMsg", "系统繁忙，请您稍后再试。");
                return modelAndView;*/
                log.error("获取openid失败："+visitIdResponse.getFailReason());
                return null;
            }
            this.getSession().setAttribute(CommonConstant.SESSION_VISIT_WX_OPENID, visitIdResponse.getModel().getOpenid());

            //根据openid获取用户信息，并自动登录
            /*ResponseDTO loginResponse=this.autoLogin();
            if(loginResponse.getResult()== ResultCodeEnum.FAILURE.code){
                *//*ModelAndView modelAndView = new ModelAndView("common/systemError");
                modelAndView.addObject("errorMsg", "系统繁忙，请您稍后再试。");
                return modelAndView;*//*
                return null;
            }*/

            //根据域名查询商家
            QueryMerchantDTO queryMerchantDTO=new QueryMerchantDTO();
            queryMerchantDTO.setEbkDomain(super.getRequest().getServerName());
            MerchantDTO merchantDTO=merchantService.queryMerchant(queryMerchantDTO);

            QuerySupplyUserBindDTO querySupplyUserBindDTO=new QuerySupplyUserBindDTO();
            querySupplyUserBindDTO.setMerchantCode(merchantDTO.getMerchantCode());
            querySupplyUserBindDTO.setOpenId(visitIdResponse.getModel().getOpenid());
            List<SupplyUserBindDO> supplyUserBindDOList=supplyService.querySupplyUserBind(querySupplyUserBindDTO);
            if (supplyUserBindDOList!=null && supplyUserBindDOList.size()>0){
                //查询供应商用户
                SingleUserRequestDTO singleUserRequestDTO=new SingleUserRequestDTO();
                singleUserRequestDTO.setMerchantId(merchantDTO.getMerchantId());
                singleUserRequestDTO.setUserId(supplyUserBindDOList.get(0).getUserId());
                ResponseDTO<SingleUserResponseDTO> singleUserResponseDTO=supplyService.getUserInfo(singleUserRequestDTO);

                EbkUserDTO ebkUserDTO=new EbkUserDTO();
                ebkUserDTO.setMerchantCode(merchantDTO.getMerchantCode());
                ebkUserDTO.setMerchantName(merchantDTO.getMerchantName());
                ebkUserDTO.setSystemName(merchantDTO.getSystemName());
                ebkUserDTO.setEbkName(merchantDTO.getEbkName());
                BeanUtils.copyProperties(singleUserResponseDTO.getModel(),ebkUserDTO);

                //查询供应商信息
                SingleUserRequestDTO supplyRequestDTO=new SingleUserRequestDTO();
                supplyRequestDTO.setSupplyId(singleUserResponseDTO.getModel().getSupplyId());
                ResponseDTO<SingleSupplyInfoResponseDTO> supplyInfoResponseDTO=supplyService.getSupplyById(supplyRequestDTO);
                if (supplyInfoResponseDTO.getResult()==ResultCodeEnum.SUCCESS.code
                        && supplyInfoResponseDTO.getModel()!=null){
                    ebkUserDTO.setSupplyCode(supplyInfoResponseDTO.getModel().getSupplyCode());
                    ebkUserDTO.setSupplyName(supplyInfoResponseDTO.getModel().getSupplyName());

                    MerchantUserDTO merchantPM=new MerchantUserDTO();
                    merchantPM.setUserId(supplyInfoResponseDTO.getModel().getMerchantPM());
                    merchantPM.setUserName(supplyInfoResponseDTO.getModel().getMerchantPMName());
                    if (merchantPM.getUserId()!=null && merchantPM.getUserId()!=0){
                        QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                        queryPMConditionDTO.setUserId(merchantPM.getUserId());
                        PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                        if (userForPage.getTotalCount()>0){
                            merchantPM.setPhone(userForPage.getItemList().get(0).getPhone());
                            merchantPM.setQq(userForPage.getItemList().get(0).getQq());
                            merchantPM.setEmail(userForPage.getItemList().get(0).getEmail());
                            merchantPM.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                        }
                    }
                    ebkUserDTO.setMerchantPM(merchantPM);

                    MerchantUserDTO merchantBM=new MerchantUserDTO();
                    merchantBM.setUserId(supplyInfoResponseDTO.getModel().getMerchantBM());
                    merchantBM.setUserName(supplyInfoResponseDTO.getModel().getMerchantBMName());
                    if (merchantBM.getUserId()!=null && merchantBM.getUserId()!=0){
                        QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                        queryPMConditionDTO.setUserId(merchantBM.getUserId());
                        PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                        if (userForPage.getTotalCount()>0){
                            merchantBM.setPhone(userForPage.getItemList().get(0).getPhone());
                            merchantBM.setQq(userForPage.getItemList().get(0).getQq());
                            merchantBM.setEmail(userForPage.getItemList().get(0).getEmail());
                            merchantBM.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                        }
                    }
                    ebkUserDTO.setMerchantBM(merchantBM);

                    MerchantUserDTO merchantFinancer=new MerchantUserDTO();
                    merchantFinancer.setUserId(supplyInfoResponseDTO.getModel().getMerchantFinancer());
                    merchantFinancer.setUserName(supplyInfoResponseDTO.getModel().getMerchantFinancerName());
                    if (merchantFinancer.getUserId()!=null && merchantFinancer.getUserId()!=0){
                        QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                        queryPMConditionDTO.setUserId(merchantFinancer.getUserId());
                        PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                        if (userForPage.getTotalCount()>0){
                            merchantFinancer.setPhone(userForPage.getItemList().get(0).getPhone());
                            merchantFinancer.setQq(userForPage.getItemList().get(0).getQq());
                            merchantFinancer.setEmail(userForPage.getItemList().get(0).getEmail());
                            merchantFinancer.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                        }
                    }
                    ebkUserDTO.setMerchantFinancer(merchantFinancer);

                    ebkUserDTO.setMerchantOPList(new ArrayList<>());
                    if (supplyInfoResponseDTO.getModel().getMerchantOPs()!=null
                            && supplyInfoResponseDTO.getModel().getMerchantOPs().size()>0){
                        for (MerchantOPDTO merchantOPDTO:supplyInfoResponseDTO.getModel().getMerchantOPs()){
                            MerchantUserDTO merchantOP=new MerchantUserDTO();
                            merchantOP.setUserId(merchantOPDTO.getMerchantOP());
                            merchantOP.setUserName(merchantOPDTO.getMerchantOPName());
                            if (merchantOP.getUserId()!=null && merchantOP.getUserId()!=0){
                                QueryUserConditionDTO queryPMConditionDTO=new QueryUserConditionDTO();
                                queryPMConditionDTO.setUserId(merchantOP.getUserId());
                                PaginationSupportDTO<UserDO> userForPage=userService.queryUserForPage(queryPMConditionDTO);
                                if (userForPage.getTotalCount()>0){
                                    merchantOP.setPhone(userForPage.getItemList().get(0).getPhone());
                                    merchantOP.setQq(userForPage.getItemList().get(0).getQq());
                                    merchantOP.setEmail(userForPage.getItemList().get(0).getEmail());
                                    merchantOP.setLandlineTelephone(userForPage.getItemList().get(0).getLandlineTelephone());
                                }
                            }
                            ebkUserDTO.getMerchantOPList().add(merchantOP);
                        }
                    }
                }
                super.getSession().setAttribute(CommonConstant.SESSION_SYSUSER,ebkUserDTO);
            }

            //业务转发
            String wxSrcVisitUrl = this.getWxSrcVisitUrl();
            if(StringUtils.isBlank(wxSrcVisitUrl)){
                response.sendRedirect(request.getContextPath() + "/ebk-mobile");
            }else{
                response.sendRedirect(wxSrcVisitUrl);
            }
            this.setWxSrcVisitUrl(null);
            return null;
        }catch(Throwable e){
            log.error("获取访问者微信信息失败："+e.getMessage(), e);
            /*ModelAndView modelAndView = new ModelAndView("common/systemError");
            return modelAndView;*/
            return null;
        }
    }
}
